Skip to content

feat(simctl): Add clone, create, and delete simulator management commands#418

Open
yjmeqt wants to merge 8 commits into
getsentry:mainfrom
yjmeqt:feat/simctl-clone-create-delete
Open

feat(simctl): Add clone, create, and delete simulator management commands#418
yjmeqt wants to merge 8 commits into
getsentry:mainfrom
yjmeqt:feat/simctl-clone-create-delete

Conversation

@yjmeqt
Copy link
Copy Markdown

@yjmeqt yjmeqt commented May 14, 2026

Summary

  • Adds clone_sims (xcrun simctl clone) — clone an existing simulator
  • Adds create_sim (xcrun simctl create) — create a new simulator
  • Adds delete_sims (xcrun simctl delete) — delete by UDID, all, or unavailable simulators (with shutdownFirst option)
  • All three tools registered under the simulator-management workflow

Closes #414

Test plan

  • Type check passes (no new errors)
  • npm run build succeeds
  • CLI help output verified for all three commands
  • Existing tests pass (no regressions)

…ands

Wraps xcrun simctl clone, create, and delete as MCP/CLI tools,
registered under the simulator-management workflow.

Co-Authored-By: deepseek v4 pro <noreply@anthropic.com>
Comment thread src/mcp/tools/simulator-management/clone_sims.ts Outdated
Comment thread src/mcp/tools/simulator-management/delete_sims.ts
Comment thread src/mcp/tools/simulator-management/clone_sims.ts Outdated
meqtMac and others added 2 commits May 14, 2026 23:28
Use NonStreamingExecutor pattern with SimulatorActionResultDomainResult,
add action types to domain-results and renderer labels.

Co-Authored-By: deepseek v4 pro <noreply@anthropic.com>
Co-Authored-By: deepseek v4 pro <noreply@anthropic.com>
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 14, 2026

Open in StackBlitz

npm i https://pkg.pr.new/xcodebuildmcp@418

commit: 7a3571c

Comment thread src/mcp/tools/simulator-management/clone_sims.ts Outdated
Comment thread src/mcp/tools/simulator-management/delete_sims.ts Outdated
Comment thread src/mcp/tools/simulator-management/clone_sims.ts Outdated
Comment thread src/mcp/tools/simulator-management/create_sim.ts Outdated
Comment thread src/mcp/tools/simulator-management/create_sim.ts Outdated
Comment thread src/mcp/tools/simulator-management/clone_sims.ts
- Fix publicSchemaObject to not omit non-session-default params
- Capture new simulator UDID from simctl clone/create stdout
- Allow shutdownFirst for delete_sims with target=all
- Add tests for clone, create, and delete tools

Co-Authored-By: deepseek v4 pro <noreply@anthropic.com>
Comment thread src/mcp/tools/simulator-management/clone_sims.ts
…on-result schema

Co-Authored-By: DeepSeek V4 Pro <noreply@deepseek.com>
Comment thread src/mcp/tools/simulator-management/clone_sims.ts Outdated
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4f8fef6. Configure here.

Comment thread src/mcp/tools/simulator-management/clone_sims.ts Outdated
cameroncooke and others added 2 commits May 26, 2026 21:30
Require clone_sims callers to provide the new simulator name that simctl expects. Avoid reporting the source simulator as a clone artifact when the clone command fails.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
Comment thread src/mcp/tools/simulator-management/clone_sims.ts
Align clone, create, and delete simulator tools with the current
simulator-action-result contract. The shared v2 schema accepts optional
top-level nextSteps and now includes the new action metadata variants.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
return;
}

const newSimulatorId = result.artifacts?.simulatorId ?? params.sourceSimulatorId;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: If xcrun simctl clone returns an empty UDID, the tool incorrectly falls back to the sourceSimulatorId, causing subsequent actions to target the original simulator instead of the clone.
Severity: HIGH

Suggested Fix

Modify the logic in clone_sims.ts to prevent falling back to sourceSimulatorId. If a valid clonedSimulatorId cannot be determined from the command output, subsequent tool suggestions like boot_sim should not be provided with a simulatorId, similar to the behavior in the create_sim tool. This ensures that actions are not accidentally performed on the source simulator.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/mcp/tools/simulator-management/clone_sims.ts#L118

Potential issue: In the `clone_sims` tool, if the `xcrun simctl clone` command succeeds
but fails to return a UDID (resulting in an empty string), the logic incorrectly falls
back to using the `sourceSimulatorId`. This happens because an empty `clonedSimulatorId`
is falsy, causing the `artifacts` object to be omitted from the result. Consequently,
the nullish coalescing operator on line 118 assigns `params.sourceSimulatorId` to
`newSimulatorId`. This incorrect ID is then used in suggestions for subsequent tools
like `boot_sim` and `install_app_sim`, causing them to operate on the original source
simulator instead of the newly created clone, defeating the purpose of the cloning
operation.

Also affects:

  • src/mcp/tools/simulator-management/clone_sims.ts:84~88

@cameroncooke
Copy link
Copy Markdown
Collaborator

Thanks @yjmeqt for putting this together — I appreciate the work here and the direction of improving simulator management.

I’ve thought this through against the original issue (#414), and I’m not convinced the current shape delivers enough value yet.

The issue is really about simulator isolation for concurrent XcodeBuildMCP usage: multiple workspaces, branches, or MCP instances may target the same simulator and interfere with each other. In that context, exposing create, clone, and delete as direct primitives is a fairly thin wrapper over xcrun simctl. An agent with shell access could already do roughly the same thing, and the current tools still require the caller to know exact runtime/device-type identifiers, manage naming, detect conflicts, and clean up safely.

I think the valuable abstraction would be higher-level, something closer to “ensure/allocate an isolated simulator”:

  • detect whether the requested/default simulator is already in use
  • clone or create a managed simulator only when isolation is needed
  • use predictable names based on project/workspace/branch/purpose
  • return the simulator ID for subsequent build/run/test/debug tools
  • only delete simulators that XcodeBuildMCP can prove it owns
  • clean up stale managed simulators safely

The low-level primitives may still be useful internally as building blocks, but I don’t think they should be the main user-facing feature for this issue. I’d prefer we reshape this PR around the simulator-isolation workflow, or narrow it explicitly as internal groundwork and follow up with the actual allocation/ownership behavior.

@cameroncooke
Copy link
Copy Markdown
Collaborator

One more note, @yjmeqt: if we continue with any version of these tool changes, the PR also needs the required snapshot fixtures/tests added for the new public tool contracts.

The contribution docs call this out here:

For new/changed tools, we should have representative fixtures for MCP text, MCP structured JSON, CLI text, and CLI JSON, plus schema fixture validation for structured output. That is especially important here because these tools expose new public CLI/MCP behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clone simulators

3 participants